Typically, computer programs are developed in a cycle of writing, compiling, executing, debugging and rewriting computer code until a satisfactory program is attained. Two types of debugging can be performed: static debugging whereby the source code comprising the computer program is analyzed and corrected for errors prior to program execution, and dynamic debugging whereby runtime errors are detected by observing the behavior of the program during execution.
A computer program can be dynamically debugged by employing a separate program or device to observe the behavior of the target computer program by monitoring memory locations. A computer program can also be dynamically debugged internally by introducing debug statements or routines into the program and observing the results during program execution. These statements can be manually introduced into the source code during the writing stage of program development. They can also be automatically introduced by a separate program at some stage in the development cycle prior to execution. The automatic introduction of debug statements or routines is known as instrumentation.
Instrumentation can be used to perform tasks useful to debugging and analyzing a computer program. These include: analyzing code coverage to determine how often each program statement is executed and how long it takes to run; analyzing variables to determine what values are taken on and how often different parts of memory are accessed; analyzing program characteristics, such as memory usage and which functions are called using which parameters; and analyzing the correct use of program code by checking various assertions that ensure that what the program is doing actually makes sense. In addition to the tasks listed above, instrumentation can be used to automatically generate test cases for dynamically testing the program. Test case data for program inputs can be generated automatically by the instrumentation which then links to a test harness program to repeatedly execute the program with different inputs.
Instrumentation can be automatically built into a computer program in a number of ways. First, instrumentation can be introduced before compilation by manipulating the source code and introducing instrumentation routines at appropriate locations. A problem with this approach is that it is slow and inefficient for large or highly complex programs.
Instrumentation can also be automatically introduced after compilation but before link editing by analyzing the relocatable object code output by the compiler. A problem with this approach is that the broader context of the target program is lost to the earlier stages of compilation. Consequently, the introduction of instrumentation must be limited to an analysis of memory locations and address pointers.
Finally, instrumentation can be automatically introduced after link editing by manipulating the executable program. This approach suffers from the same problems as with relocatable object code.
A further problem with these approaches is that the automatic introduction of instrumentation constitutes an extra stage in the program development cycle. Consequently, there is a need for a method of automatically instrumenting a computer program for dynamic debugging as an integral part of the program development cycle and without introducing an extra stage.